package cn.tedu.charging.order.service;

import cn.tedu.charging.common.constant.AmqpComponentConst;
import cn.tedu.charging.common.constant.MqttDestinationConst;
import cn.tedu.charging.common.pojo.message.ChargingStartCheckMessage;
import cn.tedu.charging.common.pojo.message.DelayCheckMessage;
import cn.tedu.charging.common.pojo.param.OrderAddParam;
import cn.tedu.charging.common.utils.CronUtil;
import cn.tedu.charging.common.utils.SnowflakeIdGenerator;
import cn.tedu.charging.common.utils.XxlJobTaskUtil;
import cn.tedu.charging.order.amqp.ProducerClient;
import cn.tedu.charging.order.mqtt.MqttProducerClient;
import cn.tedu.charging.order.feign.DeviceClient;
import cn.tedu.charging.order.feign.UserClient;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService{
    @Autowired
    private DeviceClient deviceClient;
    @Autowired
    private UserClient userClient;
    @Autowired
    private ProducerClient<DelayCheckMessage> producer;
    @Autowired
    private MqttProducerClient<ChargingStartCheckMessage> mqttProducer;
    //生成雪花算法工具类 成本员变量 数据中心id(0~31) 机器id(0~31)
    SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(10, 1);
    @Override
    public String createOrder(OrderAddParam param) {
        //1.服务调用 检查设备 和车主
        checkOk(param);
        //2.时序数据 雪花算法生成billId
        String billId = idGenerator.nextId()+ "";
        //3.给设备发送开始启动自检命令
        //3.1使用前缀常量拼接主题
        String topic = MqttDestinationConst.START_GUN_CHECK_PREFIX+param.getGunId();
        //3.2 userId gunId billId
        ChargingStartCheckMessage msg=new ChargingStartCheckMessage();
        msg.setUserId(param.getUserId());
        msg.setGunId(param.getGunId());
        msg.setOrderNo(billId);
        //3.3 发送消息
        mqttProducer.send(topic,msg);
        //4.发送延迟消息 延迟检查设备无响应
        //4.1准备一个消息对象
        DelayCheckMessage delayMsg=new DelayCheckMessage();
        delayMsg.setOrderNo(billId);
        delayMsg.setUserId(param.getUserId());
        delayMsg.setPileId(param.getPileId());
        delayMsg.setGunId(param.getGunId());
        producer.send(AmqpComponentConst.DELAY_BILL_EX,"",delayMsg);
        //5.定时任务创建,给订单充电兜底检查
        //5.1 时间计划30分钟之后 1小时之后 1.5小时之后 业务计算 订单类型 车辆剩余电量
        //为流程测试准备 2分钟
        String cronException = CronUtil.delayCron(1000 * 60 * 2);
        // //5.2 调用工具 发起http请求 创建定时任务
        XxlJobTaskUtil.createJobTask(cronException,2,billId);
        //6.修改枪状态,避免用户充电过程执行后 别的用户也来充电 status==1空闲
        deviceClient.updateGunStatus(param.getGunId(),2);
        return billId;
    }
    /*
       扫码进入 业务检查设备车主车辆之间的状态是否允许可以充电
       如果不允许充电可以 结束业务 异常
     */
    private void checkOk(OrderAddParam param) {
        log.debug("开始启动充电前的检查:userId:{},gunId:{}",param.getUserId(),param.getGunId());
        deviceClient.checkGun(param.getGunId());
        userClient.bindedVehicle(param.getUserId());
    }
}
